import datetime
import re

from flask import Blueprint, jsonify, request

from utils import sleep_redis
from utils.logger import get_logger
from utils.database import execute_query, execute_update, get_connection
from utils.redis_client import get_value, set_value, hash_getall, list_range
from utils.exceptions import (
    ValidationError,
    ResourceNotFoundError,
    DatabaseError,
    ExternalServiceError
)
import time
import random

# 创建模块专用的日志器
logger = get_logger("api.summary_data")

# 创建蓝图
summary_data_bp = Blueprint('summary_date', __name__, url_prefix='')


# 查询某一天的健康平均数据
@summary_data_bp.route('/get_health_average_data/<date>')
def get_health_average_data(date):
    # 判断日期是否合法
    if not re.match(r'^\d{4}-\d{2}-\d{2}$', date):
        ## 日期不合法
        return {
            'code': 400,
        }

    ## 医院健康平均数据
    res = {
        # 平均健康指数评分
        'score': 0,
        # 心率异常人数
        'hr_exception_cnt': 0,
        # 呼吸异常人数
        'breath_exception_cnt':0,
        # 睡眠异常人数
        'sleep_exception_cnt': 0,
        # 总人数
        'all_cnt': 0,
        'code': 200,
        'exist_data': False
    }
    ## 连接数据库
    ## 从summary表中获取date这天的数据
    sql = "SELECT * FROM summary WHERE summary_date = '" + date + "'"
    summary_data = execute_query(sql)
    if len(summary_data) > 0:
        summary_data = summary_data[0]
        res['score'] = summary_data['average_score']
        res['hr_exception_cnt'] = summary_data['hr_exception_cnt']
        res['breath_exception_cnt'] = summary_data['rr_exception_cnt']
        res['sleep_exception_cnt'] = summary_data['sleep_exception_cnt']
        res['all_cnt'] = summary_data['all_cnt']
        res['exist_data'] = True
    return res

# 人员心率血压检测
@summary_data_bp.route('/get_hrv_pressure_exception_data/<date>')
def get_hrv_pressure_exception_data(date):

    if not re.match(r'^\d{4}-\d{2}-\d{2}$', date):
        ## 日期不合法
        return {
            'code': 400,
        }

    res = {
        # 心率血压异常人数
        'exception_cnt': 0,
        # 心率过速人数
        'hrv_overspeed_cnt': 0,
        # 心率过缓人数
        'hrv_slowspeed_cnt': 0,
        # 血压异常人数
        'pressure_exception_cnt': 0,
        # 总人数
        'all_cnt': 0,
        'code': 200,
        'exist_data': False
    }
    ## 从summary表中获取date这天的数据
    sql = "SELECT * FROM summary WHERE summary_date = '" + date + "'"
    summary_data = execute_query(sql)
    if len(summary_data) > 0:
        summary_data = summary_data[0]
        res['exception_cnt'] = summary_data['hr_pressure_exception_cnt']
        res['hrv_overspeed_cnt'] = summary_data['hr_overspeed_cnt']
        res['hrv_slowspeed_cnt'] = summary_data['hr_slowspeed_cnt']
        res['pressure_exception_cnt'] = summary_data['pressure_exception_cnt']
        res['all_cnt'] = summary_data['all_cnt']
        res['exist_data'] = True
    return res
## 人员健康看护面板
@summary_data_bp.route('/get_guard_panel_data')
def get_guard_panel_data():
    # 返回每个老人的数据
    res = []
    ## 用户ID， 姓名， MAC地址， 血压阈值， 房间号, 房间ID
    sql = "select `user`.Uid,`checkin`.`name`, DataName, `user`.sbp, `user`.dbp, room.room_number, room.room_id from `user` LEFT JOIN checkin ON `user`.Uid = checkin.uid LEFT JOIN bed ON checkin.bed_id = bed.bed_id LEFT JOIN room ON room.room_id = bed.room_id WHERE checkin.checkin_state = 1"
    userData = execute_query(sql)
    for user in userData:
        res.append({
            'uid': user['Uid'],
            'mac': user['DataName'],
            'sbp': user['sbp'],
            'dbp': user['dbp'],
            'room_number': user['room_number'],
            'room_id': user['room_id'],
            'name': user['name'],
            'bed_state': 0,
            'hr': 0,
            'rr': 0,
            'sp': 0,
            'dp': 0,
            ## 深睡比例
            'dsr': 0,
            ## 浅睡比例
            'lsr': 0,
            ## 眼动比例
            'remr': 0,
            ## 睡眠周期
            'sleep_period': 0,
            ## 心脏总能量指数
            'cardiac_energy_index': 0,
            ## 平均心率
            'avg_hr': 0,
            ## 神经系统指数
            'nervous_system_index': 0,
            ## 心率减速力
            'hrdf': 0,
            ## 心脑血管时间风险指数
            'hv_risk_index': 0,
            ## 情绪压力
            'emotional_pressure': 0,
            ## 疲劳指数
            'fatigue_index': 0,
            ## 抗压指数
            'compression_resistance_index': 0,
            ## 设备是否在线
            'online': False,
        })
        if user['DataName'] == None:
            continue
        ## 从实时数据表查询该用户的心率，呼吸，收缩压，舒张压信息(这个可以不要，由后端推送)
        sql = "SELECT * FROM `" + str(user['DataName']) + "` ORDER BY TM DESC LIMIT 1";
        ## 查询最新的数据
        data = execute_query(sql)
        if len(data) > 0:
            data = data[0]
            ## 获取心率，呼吸，收缩压，舒张压
            res[-1]['hr'] = data['HR']
            res[-1]['rr'] = data['RR']
            res[-1]['sp'] = data['SP']
            res[-1]['dp'] = data['DP']
            res[-1]['bed_state'] = data['SV']
        date = datetime.datetime.now()
        dateEnd = date + datetime.timedelta(days=1)
        date = date - datetime.timedelta(hours=6)
        ## 从-00表中获取睡眠记录
        sql = "SELECT * FROM `" + str(user['DataName']) + "-00` WHERE BTM >= '" + str(date) + "' AND BTM < '" + str(dateEnd) + "' order by BTM limit 1"
        data = execute_query(sql)
        if len(data):
            data = data[0]
            ## 睡眠相关数据
            res[-1]['dsr'] = data['DSR']
            res[-1]['lsr'] = data['LSR']
            res[-1]['remr'] = data['REMR']
            res[-1]['sleep_period'] = data['SleepCycle']
            ## HRV相关数据
            ## 心脏总能量指数
            res[-1]['cardiac_energy_index'] = data['TotalCardiacEnergy']
            ## 平均心率
            res[-1]['avg_hr'] = data['AHR']
            ## 神经系统指数
            res[-1]['nervous_system_index'] = data['NervousSystemIndex']
            ## 心率减速力
            res[-1]['hrdf'] = data['HRDF']
            ## 计算情绪压力
            emotion_indicator = data['NervousSystemIndex']
            # 假设 emotion_indicator 已经定义
            if emotion_indicator >= 5:
                emotion_indicator = 4.8
            deal_indicator_ok = 0
            if emotion_indicator >= 0.4 and emotion_indicator < 1.6 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                abs_val = abs(emotion_indicator - 1)
                emotion_indicator = 100 - (abs_val / 0.6) * 30
            if emotion_indicator >= 2.56 and emotion_indicator < 3.46 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                abs_val = abs(emotion_indicator - 3.01)
                emotion_indicator = 100 - (abs_val / 0.45) * 30
            if emotion_indicator >= 1.6 and emotion_indicator <= 2.56 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                abs_val = abs(emotion_indicator - 2.08)
                emotion_indicator = 40 + abs_val * (30 / 0.48)
            if emotion_indicator < 0.4 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                emotion_indicator = 40 - (emotion_indicator / 0.4) * 40
            if emotion_indicator > 3.46 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                emotion_indicator = 40 - (emotion_indicator - 3.46) * (40 / 1.54)
            # 格式化为一位小数
            emotion_indicator = float("{:.1f}".format(emotion_indicator))
            res[-1]['emotional_pressure'] = emotion_indicator
            ## 心脑血管事件风险指数
            res[-1]['hv_risk_index'] = data['CardiovascularEventIndex']
            ## 疲劳指数
            res[-1]['fatigue_index'] = data['FatigueIndex']
            ## 抗压指数
            res[-1]['compression_resistance_index'] = data['CompressionResistanceIndex']
        # sql = "SELECT * FROM `" + str(user['DataName']) + "-00` WHERE BTM >= '" + str(date) + "' AND BTM < '" + str(dateEnd) + "'"
    return {
        'data': res,
        'code': 200
    }

# 查询全局设备状况
@summary_data_bp.route('/get_global_dev_state')
def get_global_dev_state():
    res = {

        'data': {
            ## 最近两天的summary数据
            'summary_data': [],
            ## 设备总数
            'all_dev_cnt': 0,
            ## 在线设备数量
            'online_dev_cnt': 0,
        },
        'code': 200
    }

    sql = "SELECT * FROM summary ORDER BY summary_date DESC LIMIT 2"

    data = execute_query(sql)
    res['data']['summary_data'] = data
    ## 获取设备总数
    sql = "SELECT `user`.DataName FROM `user` RIGHT JOIN checkin ON `user`.Uid = checkin.uid WHERE `user`.DataName IS NOT NULL"

    res['data']['all_dev_cnt']  = len(execute_query(sql))
    res['data']['online_dev_cnt'] = len(sleep_redis.get_online_devices())

    return res


## 查询医院的所有病人详细状态
@summary_data_bp.route('/get_patient_detail_state')
def get_patient_detail_state():
    res = {
        'data': [],
        'code': 200
    }
    sql = "SELECT `user`.Uid,`checkin`.`name`, DataName, `user`.sbp, `user`.dbp, room.room_number, room.room_id,room.room_floor, bed.position_x, bed.position_y, bed.position_z from `user` RIGHT JOIN checkin ON `user`.Uid = checkin.uid LEFT JOIN bed ON checkin.bed_id = bed.bed_id LEFT JOIN room ON room.room_id = bed.room_id WHERE checkin.checkin_state = 1"
    userData = execute_query(sql)
    for user in userData:
        resultItem = {
            ## 血压高压阈值
            "sbp": user['sbp'],
            ## 血压低压阈值
            "dbp": user['dbp'],
            ## 是否睡眠异常(这个不是每秒都有新数据所有直接返回上次睡眠是否异常)
            "sleep_exception": False,
            ## 是否HRV数据异常
            "hrv_exception": False,
            ## 床位ID
            "bed_id": user['room_id'],
            ## mac地址
            "mac": user['DataName'],
            ## 基于报告得到的数据
            "dsr": 0,
            "lsr": 0,
            "remr": 0,
            "sleep_period": 0,
            "cardiac_energy_index": 0,
            "avg_hr": 0,
            ## 神经系统指数
            'nervous_system_index': 0,
            ## 心率减速力
            'hrdf': 0,
            ## 心脑血管时间风险指数
            'hv_risk_index': 0,
            ## 情绪压力
            'emotional_pressure': 0,
            ## 疲劳指数
            'fatigue_index': 0,
            ## 抗压指数
            'compression_resistance_index': 0,
            ## 以下为实时数据，不写入，只是传一个key
            ## 收缩压
            "sp": 0,
            ## 舒张压
            "dp": 0,
            ## 心率
            "hr": 0,
            ## 呼吸率
            "rr": 0,
            ## 床位模型位置
            "position": None,
            ## 床位楼层
            "floor": user['room_floor'],
        }
        if user['position_x'] is not None:
            resultItem['position'] = {
                'x': user['position_x'],
                'y': user['position_y'],
                'z': user['position_z']
            }
        ## 睡眠异常判定
        ## 获取今天的睡眠记录
        date = datetime.datetime.now()
        dateEnd = date + datetime.timedelta(days=1)
        date = date - datetime.timedelta(hours=6)
        if(str(user['DataName']) == 'None'):
            res['data'].append(resultItem)
            continue
        ## 从-00表中获取睡眠记录
        sql = "SELECT * FROM `" + str(user['DataName']) + "-00` WHERE BTM >= '" + str(date) + "' AND BTM < '" + str(dateEnd) + "'"
        todayReport = execute_query(sql)
        for report in todayReport:
            ## 判断睡眠异常
            if (report['DSR'] > 20 or report['DSR'] < 15) or (report['LSR'] > 65 or report['LSR'] < 50) or (report['REMR'] > 25 or report['REMR'] < 20) or (report['SleepCycle'] > 6 or report['SleepCycle'] < 4):
                resultItem['sleep_exception'] = True
            ## 判断HRV异常
            ## 判断心脏总能量指数是否正常(todo:这里是用预警的还是危险的阈值)
            if (report['TotalCardiacEnergy'] > 6000 or report['TotalCardiacEnergy'] < 1000):
                resultItem['hrv_exception'] = True
            ## 判断平均心率是否正常
            if (report['AHR'] > 120 or report['AHR'] < 60):
                resultItem['hrv_exception'] = True
            ## 判断神经系统指数是否正常
            if (report['NervousSystemIndex'] > 100 or report['NervousSystemIndex'] < 50):
                resultItem['hrv_exception'] = True
            ## 判断心率减速力是否正常
            if (report['HRDF'] < 4.5 or report['HRDF'] > 10000):
                resultItem['hrv_exception'] = True
            ## 判断情绪压力是否正常
            ## 先计算情绪压力指数
            emotion_indicator = report['NervousSystemIndex']
            # 假设 emotion_indicator 已经定义
            if emotion_indicator >= 5:
                emotion_indicator = 4.8
            deal_indicator_ok = 0
            if emotion_indicator >= 0.4 and emotion_indicator < 1.6 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                abs_val = abs(emotion_indicator - 1)
                emotion_indicator = 100 - (abs_val / 0.6) * 30
            if emotion_indicator >= 2.56 and emotion_indicator < 3.46 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                abs_val = abs(emotion_indicator - 3.01)
                emotion_indicator = 100 - (abs_val / 0.45) * 30
            if emotion_indicator >= 1.6 and emotion_indicator <= 2.56 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                abs_val = abs(emotion_indicator - 2.08)
                emotion_indicator = 40 + abs_val * (30 / 0.48)
            if emotion_indicator < 0.4 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                emotion_indicator = 40 - (emotion_indicator / 0.4) * 40
            if emotion_indicator > 3.46 and deal_indicator_ok == 0:
                deal_indicator_ok = 1
                emotion_indicator = 40 - (emotion_indicator - 3.46) * (40 / 1.54)
            # 格式化为一位小数
            emotion_indicator = float("{:.1f}".format(emotion_indicator))
            if emotion_indicator > 100:
                emotion_indicator = 100
            if emotion_indicator < 40:
                resultItem['hrv_exception'] = True
            ## 判断疲劳指数是否异常
            if (report['FatigueIndex'] < 40):
                resultItem['hrv_exception'] = True
            ## 抗压指数是否异常
            if (report['CompressionResistanceIndex'] < 40):
                resultItem['hrv_exception'] = True
            ## 填入报告数据
            resultItem['dsr'] = report['DSR']
            resultItem['lsr'] = report['LSR']
            resultItem['remr'] = report['REMR']
            resultItem['sleep_period'] = report['SleepCycle']
            resultItem['cardiac_energy_index'] = report['TotalCardiacEnergy']
            resultItem['avg_hr'] = report['AHR']
            resultItem['nervous_system_index'] = report['NervousSystemIndex']
            resultItem['hrdf'] = report['HRDF']
            resultItem['hv_risk_index'] = report['CardiovascularEventIndex']
            resultItem['emotional_pressure'] = emotion_indicator
            resultItem['fatigue_index'] = report['FatigueIndex']
            resultItem['compression_resistance_index'] = report['CompressionResistanceIndex']
        res['data'].append(resultItem)
    return res
            ##
## 获取一个星期的summary数据
@summary_data_bp.route('/get_week_summary_data/<date>')
def get_week_summary_data(date):
    # 验证日期格式
    if not re.match(r'^\d{4}-\d{2}-\d{2}$', date):
        return {
            'code': 400,
            'message': '日期格式不合法'
        }

    # 转换日期为datetime对象
    try:
        date = datetime.datetime.strptime(date, "%Y-%m-%d")
    except ValueError:
        return {
            'code': 400,
            'message': '日期格式不合法'
        }

    # 计算起始日期
    dateBegin = date - datetime.timedelta(days=6)

    # 连接数据库

    # 查询数据
    sql = """
    SELECT * FROM summary 
    WHERE summary_date BETWEEN %s AND %s
    ORDER BY summary_date
    """
    summaryData = execute_query(sql,  (dateBegin.date(), date.date()))

    # 生成完整的日期列表
    date_list = []
    current_date = dateBegin
    while current_date <= date:
        date_list.append(current_date.date())
        current_date += datetime.timedelta(days=1)

    # 填充缺失的日期数据
    result = []
    data_dict = {item['summary_date']: item for item in summaryData}
    all_cnt = 0
    for d in date_list:
        if d in data_dict:
            all_cnt = data_dict[d]['all_cnt']
            result.append(data_dict[d])
        else:
            # 填充默认值
            result.append({
                'summary_id': 0,
                'summary_date': d,
                'hr_exception_cnt': 0,
                'pressure_exception_cnt': 0,
                'rr_exception_cnt': 0,
                'sleep_exception_cnt': 0,
                'hrv_watch_exception_cnt': 0,
                'create_time': datetime.datetime.now(),
                'all_cnt': all_cnt,
                'exception_cnt': 0,
                'average_score': 0.00,
                'cv_exception_cnt': 0
            })
    return {
        'data': result,
        'code': 200,
    }
## 人员呼吸健康指数接口
@summary_data_bp.route('/get_breath_health_index_data/<date>')
def get_breath_health_index_data(date):
    if not re.match(r'^\d{4}-\d{2}-\d{2}$', date):
        ## 日期不合法
        return {
            'code': 400,
        }

    res = {
        # 总人数
        'all_cnt': 0,
        # 异常人数
        'exception_cnt': 0,
        # 呼吸过速人数
        'breath_overspeed_cnt': 0,
        # 呼吸过缓人数
        'breath_slowspeed_cnt': 0,
        # 呼吸暂停人数
        'breath_pause_cnt': 0,
        "code": 200,    
        'exist_data': False
    }
    ## 从summary表中获取date这天的数据
    sql = "SELECT * FROM summary WHERE summary_date = '" + date + "'"
    summary_data = execute_query(sql)
    if len(summary_data) > 0:
        summary_data = summary_data[0]
        res['breath_overspeed_cnt'] = summary_data['rr_overspeed_cnt']
        res['breath_slowspeed_cnt'] = summary_data['rr_slowspeed_cnt']
        res['breath_pause_cnt'] = summary_data['rr_pause_cnt']
        res['all_cnt'] = summary_data['all_cnt']
        res['exception_cnt'] = summary_data['exception_cnt']
        res['exist_data'] = True
    return res

## 人员睡眠健康检测
@summary_data_bp.route('/get_sleep_health_index_data/<date>')
def get_sleep_health_index_data(date):
    if not re.match(r'^\d{4}-\d{2}-\d{2}$', date):
        ## 日期不合法
        return {
            'code': 400,
        }

    ## 获取前一天下午六点到今天24点之间生成的数据，睡觉数据可能在前一天生成
    res = {
        # 总人数
        'all_cnt': 0,
        # 睡眠质量异常总人数
        'exception_cnt': 0,
        # 深浅睡眠比例失常人数
        'sleep_quality_exception_cnt': 0,
        # 睡眠快速眼动异常人数
        'sleep_fast_exception_cnt': 0,
        # 睡眠周期异常人数
        'sleep_period_exception_cnt': 0,
        'code': 200,
        'exist_data': False
    }
    ## 从summary表中获取date这天的数据
    sql = "SELECT * FROM summary WHERE summary_date = '" + date + "'"
    summary_data = execute_query(sql)
    if len(summary_data) > 0:
        summary_data = summary_data[0]
        res['all_cnt'] = summary_data['all_cnt']
        res['exception_cnt'] = summary_data['exception_cnt']
        res['sleep_quality_exception_cnt'] = summary_data['deep_light_sleep_exception_cnt']
        res['sleep_fast_exception_cnt'] = summary_data['rem_exception_cnt']
        res['sleep_period_exception_cnt'] = summary_data['sleep_cycle_exception_cnt']
        res['exist_data'] = True
    return res

## 人员生命体征监测统计
@summary_data_bp.route('/get_life_sign_wave_data/<date>')
def get_life_sign_wave_data(date):
    if not re.match(r'^\d{4}-\d{2}-\d{2}$', date):
        ## 日期不合法
        return {
            'code': 400,
        }
    date = datetime.datetime.strptime(date, "%Y-%m-%d")
    ## date的7天前
    dateBefore = date - datetime.timedelta(days=6)
    res = []
    ## 先搜索前6天的数据
    sql = "SELECT * FROM summary where summary_date >= " + dateBefore.strftime("%Y-%m-%d") + " AND summary_date < " + date.strftime("%Y-%m-%d")
    data = execute_query(sql)
    for d in data:
        res.append(d)
    ## 解析今天的summary并添加进去
    res.append(parse_today_summary(date.strftime("%Y-%m-%d")))
    return res

@summary_data_bp.route('/get_today_summary_data/<date>')
## 解析今日的summary数据并返回
def parse_today_summary(date):
    date = datetime.datetime.strptime(date, "%Y-%m-%d")
    dateEnd = date + datetime.timedelta(days=1)
    date = date - datetime.timedelta(hours=6)
    res = {
        'summary_id': -1,
        'summary_date': date.strftime("%Y-%m-%d"),
        ## 心率异常人数
        'hr_exception_cnt': 0,
        ## 血压异常人数
        'pressure_exception_cnt': 0,
        ## 呼吸异常人数
        'rr_exception_cnt': 0,
        ## 睡眠异常人数
        'sleep_exception_cnt': 0,
        ## hrv监测异常
        'hrv_watch_exception_cnt': 0,
        ## 总人数
        'all_cnt': 0,
        ## 异常总人数
        'exception_cnt': 0,
        ## 平均健康指数
        'average_score': 0.,
    }
    sql = "SELECT * FROM user WHERE DataName IS NOT NULL AND DataName != ''"
    userData = execute_query(sql)
    ## 总分数，用来求平均分
    score = 0
    for user in userData:
        exception_flag = False
        sql = "SELECT * FROM `" + str(user['DataName']) + "-00` WHERE BTM >= '" + str(date) + "' AND BTM < '" + str(dateEnd) + "'"
        data = execute_query(sql)
        hr_exception = 0
        rr_exception = 0
        pressure_exception = 0
        ## 当前用户的分数
        current_score = 0
        current_cnt = 0
        for d in data:
            current_score += d['Score']
            current_cnt += 1
            ## 判断心率是否异常
            if d['HRHigh'] > 0 or d['HRLow'] > 0:
                exception_flag = True
                hr_exception = 1
            ## 判断呼吸是否异常
            if d['RRHigh'] > 0 or d['RRLow'] > 0:
                exception_flag = True
                rr_exception = 1
            ## 判断血压异常
            ## 血压异常判断要去PlotDB表中判断
            sql = "SELECT * FROM `" + str(d['PlotDB']) + "`"
            ## 详细数据
            cc_data = execute_query(sql)
            for cc in cc_data:
                if cc['SP'] > user['sbp'] or cc['SP'] < user['dbp'] or cc['DP'] > user['sbp'] or cc['DP'] < user['dbp']:
                    exception_flag = True
                    pressure_exception = 1
                    break
            ## 判断睡眠质量异常(todo)

            ## HRV监测异常
        ## 人数+1
        res['all_cnt'] += 1
        if exception_flag:
            res['exception_cnt'] += 1
        ## 各个异常
        res['hr_exception_cnt'] += hr_exception
        res['rr_exception_cnt'] += rr_exception
        res['pressure_exception_cnt'] += pressure_exception
        score += current_score
    res['average_score'] = score / res['all_cnt']
    return res
